import { Graph, Shape } from '@antv/x6';
import { Clipboard } from '@antv/x6-plugin-clipboard';
import { History } from '@antv/x6-plugin-history';
import { Keyboard } from '@antv/x6-plugin-keyboard';
import { Scroller } from '@antv/x6-plugin-scroller';
import { Selection } from '@antv/x6-plugin-selection';
import { Snapline } from '@antv/x6-plugin-snapline';
import { Stencil } from '@antv/x6-plugin-stencil';
import { Transform } from '@antv/x6-plugin-transform';
import { register } from '@antv/x6-react-shape';
import { useEffect, useRef } from 'react';
import AlgoNode from './components/AlgoNode';
import FlowForm from './components/FlowForm';

// #region 初始化图形
const ports = {
  groups: {
    top: {
      position: 'top',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
    right: {
      position: 'right',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
    bottom: {
      position: 'bottom',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
    left: {
      position: 'left',
      attrs: {
        circle: {
          r: 4,
          magnet: true,
          stroke: '#5F95FF',
          strokeWidth: 1,
          fill: '#fff',
          style: {
            visibility: 'hidden',
          },
        },
      },
    },
  },
  items: [
    {
      group: 'top',
    },
    {
      group: 'right',
    },
    {
      group: 'bottom',
    },
    {
      group: 'left',
    },
  ],
};
// Graph.registerNode(
//   'custom-image',
//   {
//     inherit: 'rect',
//     width: 52,
//     height: 52,
//     markup: [
//       {
//         tagName: 'rect',
//         selector: 'body',
//       },
//       {
//         tagName: 'image',
//       },
//       {
//         tagName: 'text',
//         selector: 'label',
//       },
//     ],
//     attrs: {
//       body: {
//         stroke: '#5F95FF',
//         fill: '#5F95FF',
//       },
//       image: {
//         width: 26,
//         height: 26,
//         refX: 13,
//         refY: 16,
//       },
//       label: {
//         refX: 3,
//         refY: 2,
//         textAnchor: 'left',
//         textVerticalAnchor: 'top',
//         fontSize: 12,
//         fill: '#333',
//       },
//     },
//     ports: { ...ports },
//   },
//   true,
// );
const MenuNodeItem = (props: any) => {
  const { node } = props;
  const data = node?.getData();
  const { label, imgURL, status = 'default' } = data;
  return <img src={imgURL} style={{ width: '40px', height: '40px' }} alt="" />;
};
const X6Graph = () => {
  const containerRef1 = useRef(null);

  useEffect(() => {
    // #endregion
    const graph1: any = new Graph({
      resizing: {
        enabled: false,
      },
      container: containerRef1.current as any,
      panning: {
        enabled: true,
        eventTypes: ['leftMouseDown', 'mouseWheel'],
      },
      highlighting: {
        magnetAdsorbed: {
          name: 'stroke',
          args: {
            attrs: {
              fill: '#fff',
              stroke: '#31d0c6',
              strokeWidth: 4,
            },
          },
        },
      },
      background: {
        color: '#F2F7FA',
      },
      // 网格线
      grid: {
        visible: true,
        type: 'doubleMesh',
        args: [
          {
            color: '#eee', // 主网格线颜色
            thickness: 1, // 主网格线宽度
          },
          {
            color: '#ddd', // 次网格线颜色
            thickness: 1, // 次网格线宽度
            factor: 4, // 主次网格线间隔
          },
        ],
      },
      mousewheel: {
        enabled: true,
        zoomAtMousePosition: true,
        modifiers: 'ctrl',
        minScale: 0.5,
        maxScale: 3,
      },
      connecting: {
        router: 'manhattan',
        connector: {
          name: 'rounded',
          args: {
            radius: 8,
          },
        },
        anchor: 'center',
        connectionPoint: 'anchor',
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: '#A2B1C3',
                strokeWidth: 2,
                targetMarker: {
                  name: 'block',
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }: any) {
          return !!targetMagnet;
        },
      },
    } as any);
    // 初始化插件 ( 左侧菜单的节点插件 )
    graph1
      .use(
        new Transform({
          resizing: true,
          rotating: true,
        }),
      )
      .use(
        new Selection({
          multiple: true,
          rubberEdge: true,
          rubberNode: true,
          modifiers: 'shift',
          rubberband: true,
        }),
      )
      .use(new Snapline())
      .use(new Keyboard())
      .use(new Clipboard())
      .use(new History())
      .use(
        new Scroller({
          enabled: true,
        }),
      );
    // 添加自定义限制逻辑，禁止缩放
    graph1.on('node:change:size', ({ node, options }: any) => {
      if (options.resize) {
        const { width, height } = options;
        node.size(width, height, { restrict: true });
        return false; // 禁止默认的缩放行为
      }
    });
    // #region 快捷键与事件
    graph1.bindKey(['meta+c', 'ctrl+c'], () => {
      const cells = graph1.getSelectedCells();
      if (cells.length) {
        graph1.copy(cells);
      }
      return false;
    });
    graph1.bindKey(['meta+x', 'ctrl+x'], () => {
      const cells = graph1.getSelectedCells();
      if (cells.length) {
        graph1.cut(cells);
      }
      return false;
    });
    graph1.bindKey(['meta+v', 'ctrl+v'], () => {
      if (!graph1.isClipboardEmpty()) {
        const cells = graph1.paste({ offset: 32 });
        graph1.cleanSelection();
        graph1.select(cells);
      }
      return false;
    });

    // undo redo
    graph1.bindKey(['meta+z', 'ctrl+z'], () => {
      if (graph1.canUndo()) {
        graph1.undo();
      }
      return false;
    });
    graph1.bindKey(['meta+shift+z', 'ctrl+shift+z'], () => {
      if (graph1.canRedo()) {
        graph1.redo();
      }
      return false;
    });

    // select all
    graph1.bindKey(['meta+a', 'ctrl+a'], () => {
      const nodes = graph1.getNodes();
      if (nodes) {
        graph1.select(nodes);
      }
    });

    // delete
    graph1.bindKey('backspace', () => {
      const cells = graph1.getSelectedCells();
      if (cells.length) {
        graph1.removeCells(cells);
      }
    });

    // zoom
    graph1.bindKey(['ctrl+1', 'meta+1'], () => {
      const zoom = graph1.zoom();
      if (zoom < 1.5) {
        graph1.zoom(0.1);
      }
    });
    graph1.bindKey(['ctrl+2', 'meta+2'], () => {
      const zoom = graph1.zoom();
      if (zoom > 0.5) {
        graph1.zoom(-0.1);
      }
    });

    // #region 初始化 stencil
    const stencil = new Stencil({
      title: ' ',
      target: graph1,
      // stencilGraphWidth: 170,
      stencilGraphHeight: 0,
      collapsable: false,
      groups: [
        {
          title: '加工工序',
          name: 'group1',
        },
        {
          title: '检验工序',
          name: 'group2',
        },
        {
          title: '存储及其它',
          name: 'group3',
        },
      ],
      layoutOptions: {
        background: '#fff',
        columns: 1,
        columnWidth: 'auto',
        rowHeight: 45,
      },
    });
    document.getElementById('stencil1')!.appendChild(stencil.container);
    register({
      shape: 'dag-node',
      width: 140,
      height: 36,
      resizable: false,
      component: AlgoNode,
      // x: 20,
      // 连接线的配置
      ports: {
        ...ports,
      },
    });
    // 节点-加工工序
    const imageShapesMachiningProcedure = [
      {
        label: '入库检测',
        image: '/images/ruku-jiance.png',
      },
      {
        label: '清洗',
        image: '/images/qingxi.png',
      },
      {
        label: '涂膜',
        image: '/images/tumo.png',
      },
      {
        label: '透光率检验',
        image: '/images/touguang.png',
      },
    ];
    // 节点-检验检验
    const imageShapesTestProcedure = [
      {
        label: '真空性能检验',
        image: '/images/zhenkongxingnneng.png',
      },
      {
        label: '表面状态检验',
        image: '/images/biaomian.png',
      },
    ];
    // 节点-检验检验
    const imageShapesWork = [
      {
        label: '运转',
        image: '/images/yunzhuan.png',
      },
    ];
    const imageNodes1 = imageShapesMachiningProcedure.map((item) =>
      graph1.createNode({
        shape: 'dag-node',
        data: {
          label: item.label,
          imgURL: item.image,
        },
      }),
    );
    const imageNodes2 = imageShapesTestProcedure.map((item) =>
      graph1.createNode({
        shape: 'dag-node',
        data: {
          label: item.label,
          imgURL: item.image,
        },
      }),
    );
    const imageNodes3 = imageShapesWork.map((item) =>
      graph1.createNode({
        shape: 'dag-node',
        data: {
          label: item.label,
          imgURL: item.image,
        },
      }),
    );
    stencil.load(imageNodes1, 'group1');
    stencil.load(imageNodes2, 'group2');
    stencil.load(imageNodes3, 'group3');
    // 控制连接桩显示/隐藏
    const showPorts = (ports: NodeListOf<SVGElement>, show: boolean) => {
      for (let i = 0, len = ports.length; i < len; i += 1) {
        ports[i].style.visibility = show ? 'visible' : 'hidden';
      }
    };
    graph1.on('node:mouseenter', () => {
      const container = document.getElementById('graph1-container')!;

      const ports = container.querySelectorAll('.x6-port-body') as NodeListOf<SVGElement>;
      showPorts(ports, true);
    });
    graph1.on('node:mouseleave', () => {
      const container = document.getElementById('graph1-container')!;
      const ports = container.querySelectorAll('.x6-port-body') as NodeListOf<SVGElement>;
      showPorts(ports, false);
    });
    graph1.on('node:click', ({ node }) => {
      console.log('node :>> ', node?.getData());
    });
    // return () => {
    //   graph1.dispose();
    // };
  }, []);

  return (
    <div style={{ display: 'flex' }}>
      <div id={'stencil1'} style={{ minWidth: '180px', maxWidth: '180px' }}></div>
      <div
        key={111}
        ref={containerRef1}
        style={{ width: 'calc(100% - 170px - 220px)', height: 500 }}
        id="graph1-container"
      />
      <FlowForm></FlowForm>
    </div>
  );
};
// 我们用 insert-css 演示引入自定义样式
// 推荐将样式添加到自己的样式文件中
// 若拷贝官方代码，别忘了 npm install insert-css
export default X6Graph;
